using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using OsdmSoftware.CommonLibrary;
using System.Drawing;

namespace OsdmSoftware.PocketPicture
{
    public class HSVDropDownControl: UserControl, IDropDownControl
    {
        HueSaturationControl hueSaturationControl = new HueSaturationControl();
        LuminanceControl luminanceControl = new LuminanceControl();
        Button button = new Button();
        PocketPictureForm form;
        ColorElement colorElement;

        public ColorElement ColorElement { get { return colorElement; } set { colorElement = value; } }

        public PocketPictureForm Form { get { return form; } set { form = value; } }

        public HSVDropDownControl(PocketPictureForm form, ColorElement element)
        {
            this.Controls.Add(hueSaturationControl);
            this.Controls.Add(luminanceControl);
            this.Controls.Add(button);
            button.Text = "OK";
            button.Click += new EventHandler(button_Click);
            hueSaturationControl.SelectedColorChanged += new EventHandler(hueSaturationControl_SelectedColorChanged);
            luminanceControl.SelectedValueChanged += new EventHandler(luminanceControl_SelectedValueChanged);
            this.form = form;
            this.colorElement = element;
        }

        public Color ColorEdit
        {
            get
            {
                return button.BackColor;
            }

            set
            {
                button.BackColor = value;
                hueSaturationControl.SelectedColor = value;
                luminanceControl.SelectedColor = HueSaturationControl.HSVToColor(hueSaturationControl.SelectedHue, hueSaturationControl.SelectedSaturation, 255);
                luminanceControl.SelectedValue = hueSaturationControl.SelectedValue;
                if (hueSaturationControl.SelectedValue > 128)
                    button.ForeColor = Color.Black;
                else
                    button.ForeColor = Color.White;

                button.Refresh();
            }
        }

        void luminanceControl_SelectedValueChanged(object sender, EventArgs e)
        {
            hueSaturationControl.SelectedValue = (byte) luminanceControl.SelectedValue;
            ColorEdit = hueSaturationControl.SelectedColor;
        }

        void hueSaturationControl_SelectedColorChanged(object sender, EventArgs e)
        {
            ColorEdit = hueSaturationControl.SelectedColor;
        }

        void button_Click(object sender, EventArgs e)
        {
            if (colorElement != null)
            {
                colorElement.Color = ColorEdit;
                colorElement.Refresh();
            }

            form.PaletteSelectedColor = ColorEdit;
            OnCloseParentDropDown();
        }

        public event EventHandler CloseParentDropDown;

        protected Size OrientShortHorizontal(int maxWidth, int maxHeight)
        {
            hueSaturationControl.Orientation = Orientation.Horizontal;
            hueSaturationControl.Initialize();
            hueSaturationControl.Location = new Point(0, 0);

            button.Location = new Point(0, hueSaturationControl.Height);
            button.Height = Math.Min(hueSaturationControl.Height / 3, maxHeight - hueSaturationControl.Height);
            button.Width = hueSaturationControl.Width / 10;

            luminanceControl.Orientation = Orientation.Horizontal;
            luminanceControl.Location = new Point(button.Width, hueSaturationControl.Height);
            luminanceControl.Height = button.Height;
            luminanceControl.Width = hueSaturationControl.Width - button.Width;

            return new Size(hueSaturationControl.Width, hueSaturationControl.Height + button.Height);
        }

        protected Size OrientShortVertical(int maxWidth, int maxHeight)
        {
            hueSaturationControl.Orientation = Orientation.Vertical;
            hueSaturationControl.Initialize();
            hueSaturationControl.Location = new Point(0, 0);

            button.Location = new Point(hueSaturationControl.Width, 0);
            button.Width = Math.Min(hueSaturationControl.Width / 3, maxWidth - hueSaturationControl.Width);
            button.Height = hueSaturationControl.Height / 10;

            luminanceControl.Orientation = Orientation.Vertical;
            luminanceControl.Location = new Point(hueSaturationControl.Width, button.Height);
            luminanceControl.Height = hueSaturationControl.Height - button.Height;
            luminanceControl.Width = button.Width;

            return new Size(hueSaturationControl.Width + button.Width, hueSaturationControl.Height);
        }

        protected Size OrientLongHorizontal(int maxWidth, int maxHeight)
        {
            hueSaturationControl.Orientation = Orientation.Horizontal;
            hueSaturationControl.Initialize();
            hueSaturationControl.Location = new Point(0, 0);

            button.Location = new Point(hueSaturationControl.Width, 0);
            button.Width = Math.Max(10, Math.Min(hueSaturationControl.Height / 3, maxWidth - hueSaturationControl.Width));
            button.Height = hueSaturationControl.Height / 10;

            luminanceControl.Orientation = Orientation.Vertical;
            luminanceControl.Location = new Point(hueSaturationControl.Width, button.Height);
            luminanceControl.Height = hueSaturationControl.Height - button.Height;
            luminanceControl.Width = button.Width;
            return new Size(hueSaturationControl.Width + button.Width, hueSaturationControl.Height);
        }

        protected Size OrientLongVertical(int maxWidth, int maxHeight)
        {
            hueSaturationControl.Orientation = Orientation.Vertical;
            hueSaturationControl.Initialize();
            hueSaturationControl.Location = new Point(0, 0);

            button.Location = new Point(0, hueSaturationControl.Height);
            button.Height = Math.Max(10, Math.Min(hueSaturationControl.Width / 3, maxHeight - hueSaturationControl.Height));
            button.Width = hueSaturationControl.Width / 10;

            luminanceControl.Orientation = Orientation.Horizontal;
            luminanceControl.Location = new Point(button.Width, hueSaturationControl.Height);
            luminanceControl.Height = button.Height;
            luminanceControl.Width = hueSaturationControl.Width - button.Width;
            luminanceControl.Orientation = Orientation.Vertical;
            return new Size(hueSaturationControl.Width, hueSaturationControl.Height + button.Height);
        }

        public Size GetOptimalSize(int maxWidth, int maxHeight)
        {
            Orientation orient;
            int minSize, maxSize;
            if (maxWidth < maxHeight)
            {
                orient = Orientation.Vertical;
                minSize = maxWidth;
                maxSize = maxHeight;
            }
            else
            {
                orient = Orientation.Horizontal;
                minSize = maxHeight;
                maxSize = maxWidth;
            }

            hueSaturationControl.Orientation = orient;
            hueSaturationControl.Initialize();
            if (Math.Min(hueSaturationControl.Width, hueSaturationControl.Height) > minSize)
            {
                MessageBox.Show("There is not enough screen space");
            }

            if (Math.Max(hueSaturationControl.Width, hueSaturationControl.Height) <= minSize)
            {
                if (orient == Orientation.Horizontal)
                {
                    return OrientShortVertical(maxWidth, maxHeight);
                }
                else
                {
                    return OrientShortHorizontal(maxWidth, maxHeight);
                }
            }
            else if (Math.Min(hueSaturationControl.Width, hueSaturationControl.Height) * 4 / 3 <= minSize)
            {
                if (Math.Max(hueSaturationControl.Width, hueSaturationControl.Height) > maxSize)
                {
                    MessageBox.Show("There is not enough screen space");
                }

                if (orient == Orientation.Horizontal)
                {
                    return OrientShortHorizontal(maxWidth, maxHeight);
                }
                else
                {
                    return OrientShortVertical(maxWidth, maxHeight);
                }
            }
            else
            {
                if (Math.Max(hueSaturationControl.Width, hueSaturationControl.Height) + Math.Min(hueSaturationControl.Width, hueSaturationControl.Height) / 2 > maxSize)
                {
                    MessageBox.Show("There is not enough screen space");
                }

                if (orient == Orientation.Horizontal)
                {
                    return OrientLongHorizontal(maxWidth, maxHeight);
                }
                else
                {
                    return OrientLongVertical(maxWidth, maxHeight);
                }
            }
        }

        public void CloseDropDown()
        {
        }

        public void ReleaseResources()
        {
            if (hueSaturationControl != null)
            {
                hueSaturationControl.Dispose();
                hueSaturationControl = null;
            }

            if (luminanceControl != null)
            {
                luminanceControl.Dispose();
                luminanceControl = null;
            }
        }

        public void Initialize()
        {
            ColorEdit = form.PaletteSelectedColor;
        }

        public Control Control
        {
            get { return this; }
        }

        public bool DisposeWithForm
        {
            get { return true; }
        }

        public float Area
        {
            get
            {
                hueSaturationControl.Orientation = Orientation.Horizontal;
                hueSaturationControl.Initialize();
                return hueSaturationControl.Width * hueSaturationControl.Height * 3 / 2;
            }
        }

        protected virtual void OnCloseParentDropDown()
        {
            if (CloseParentDropDown != null)
                CloseParentDropDown(this, EventArgs.Empty);
        }
    }
}
